package org.ww.ext;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.ww.bean.Car;

/**
 * BeanPostProcessor：bean的后置处理器
 * BeanFactoryPostProcessor：beanFactory的后置处理器
 *      1）ioc容器创建对象
 *      2）invokeBeanFactoryPostProcessors：执行BeanFactoryPostProcessor
 *              1、在beanFactory中getBeanFactoryPostProcessors获取所有得BeanFactoryPostProcessors并执行他们得方法
 *              2、在初始化其他组件前边执行
 * BeanFactoryPostProcessor的子类BeanDefinitionRegistryPostProcessor：
 *      1、BeanDefinitionRegistryPostProcessor在bean定义之前执行
 *      2、ioc->refresh->invokeBeanFactoryPostProcessors
 *      3、for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
 * 			        postProcessor.postProcessBeanDefinitionRegistry(registry);
 *             }
 *          从容器中获取所有的BeanDefinitionRegistryPostProcessor组件，
 *          依次触发所有的postProcessBeanDefinitionRegistry方法
 *          在来触发postProcessBeanFactory方法   BeanFactoryPostProcessor
 *      4、在来从容器中找到BeanFactoryPostProcessor组件，然后依次触发postProcessBeanFactory方法
 *  ApplicationListener
 *          监听ApplicationEvent
 *       步骤：
 *          1、写一个监听器来监听某个事件（ApplicationEvent及其子类）
 *          2、把监听器放入容器
 *          3、只要容器中有相关事件的发布，我们就能监听到该事件
 *              ContextRefreshedEvent：容器刷新完成（所有的bean都完全创建）会发布这个事件
 *              ContextClosedEvent：关闭容器会发布这个事件
 *       原理：
 *          1、refresh()->finishRefresh
 *          2、publishEvent
 *          3、for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
 * 			   Executor executor = getTaskExecutor();
 * 			   获取所有的监听器
 * 			   1、如果有Executor，可以支持Executor进行异步派发
 * 			   2、否则同步的方式直接执行invokeListener
 *                 listener.onApplicationEvent(event)
 *                 拿到listener回调onApplicationEvent方法
 *       【事件多播器（派发器）】
 *              1、容器创建对象：refresh();
 *              2、在这之前执行initApplicationEventMulticaster();初始化ApplicationEventMulticaster
 *              3、先在容器中获取id="applicationEventMulticaster"
 *                  如果没有获取到，this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
 *                  就会注册一个applicationEventMulticaster，把他放到容器中
 *       【有哪些listener】
 *              在finishRefresh()之前会注册所有的监听器registerListeners();
 *              getApplicationEventMulticaster().addApplicationListener(listener);
 *              String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
 *              获取所有的监听器并放到ApplicationListener中去
 * @EventListener->EventListenerMethodProcessor->SmartInitializingSingleton
 *  SmartInitializingSingleton原理：
 *      1、ioc容器创建对象并refresh()
 *      2、finishBeanFactoryInitialization(beanFactory)初始化剩下的实例bean
 *          1、先创建所有的单实例bean
 *          2、获取所有创建好的单实例bean
 *              判断该实例是否是SmartInitializingSingleton类型
 *              如果是就执行afterSingletonsInstantiated
 *
 */
@ComponentScan("org.ww.ext")
@Configuration
public class ExtConfig {
    @Bean
    public Car car(){
        return new Car();
    }
}
